from django.db.models.signals import post_save
from django.db import models
from django.core.urlresolvers import reverse
from models import Badge as BadgeModel

class MetaBadge:
    conditions = ()
    badge_info = {}
    one_time_only = False
    model = models.Model
    user_field_name = "instance.user"
    
    def __init__(self):
        # whenever the server is reloaded, the badge will be initialized and
        # added to the database
        self._keep_badge_updated()
        post_save.connect(self._signal_callback, sender=self.model)
    
    def _signal_callback(self, **kwargs):
        i = kwargs['instance']
        self.award_ceremony(i)
    
    def _test_conditions(self, instance):
        for condition in self.conditions:
            if not eval(condition):
                return False
        return True
    
    @classmethod
    def _keep_badge_updated(cls):
        badge, created = BadgeModel.objects.get_or_create(db_name = cls.badge_info['db_name'])
        badge.title = cls.badge_info['title']
        badge.description = cls.badge_info['description']
        badge.level = cls.badge_info['level']     
        badge.save()
        cls.badge = badge
    
    def award_ceremony(self, instance):
        if self._test_conditions(instance):
            user = eval(self.user_field_name)
            has_badge = self.badge in user.badges.all()
            
            # temporary (makes all posts one_time_only until I find a good way to 
            # allow users to earn a badge more than once.
            # one way to do it is to use through in the manytomany... unfortunately that
            # breaks the user.badges.add code (which very convenient)
            self.one_time_only = True
            
            if not (self.one_time_only and has_badge):
                user.badges.add(self.badge)
                message_template = "You just got the %s Badge!"
                user.message_set.create(message = message_template % self.badge.title )
            

registered_badges = [] 
def findAndCreateBadges():
    # This is the beginning of a search that finds badges all over a project :)
    import badges
    for b in badges.__dict__.values():
        if (type(b) == type(MetaBadge)) and issubclass(b, MetaBadge) and (b is not MetaBadge):
            # When we find an subclass of Badge, we want to make an instance
            # so that the signals will get connected up :) 
            registered_badges.append(b())
    return registered_badges

    